package service

import (
	"context"
	"fmt"
	"log"
	"strconv"
	"sync"
	"time"

	"WHY_GIN/config"
	"WHY_GIN/utils"

	"github.com/adshao/go-binance/v2"
)

// TakeProfitOrder 止盈订单结构
type TakeProfitOrder struct {
	OrderID       int64     `json:"order_id"`       // 订单ID
	Symbol        string    `json:"symbol"`         // 交易对
	OriginalPrice float64   `json:"original_price"` // 原始订单价格
	Quantity      float64   `json:"quantity"`       // 订单数量
	Side          string    `json:"side"`           // 订单方向（只处理BUY）
	IsActive      bool      `json:"is_active"`      // 是否激活
	CreatedAt     time.Time `json:"created_at"`     // 创建时间
	LastCheckAt   time.Time `json:"last_check_at"`  // 最后检查时间
}

// TakeProfitManager 止盈管理器
type TakeProfitManager struct {
	client            *binance.Client
	monitoredOrders   map[int64]*TakeProfitOrder // 监控的订单映射
	mu                sync.RWMutex               // 读写锁
	isRunning         bool                       // 是否正在运行
	stopChan          chan struct{}              // 停止信号通道
	resistanceLevels  map[string]float64         // 压力位价格映射（交易对 -> 压力位价格）
	breakoutTriggered map[string]bool            // 压力位突破标记（交易对 -> 是否已突破）
	breakoutPrices    map[string]float64         // 突破时的价格（交易对 -> 突破价格）
	basePositionRate  float64                    // 底仓保留比例（默认20%）
	firstSellRate     float64                    // 首次卖出比例（默认30%）
	secondSellTrigger float64                    // 二次卖出触发涨幅（默认10%）
}

// NewTakeProfitManager 创建新的止盈管理器
func NewTakeProfitManager() *TakeProfitManager {
	// 初始化Binance客户端
	client := binance.NewClient(config.Cfg.Binance.APIKey, config.Cfg.Binance.SecretKey)
	if config.Cfg.Binance.UseTestnet {
		client.BaseURL = "https://testnet.binance.vision"
	}

	// 初始化时间同步
	timeSyncManager := utils.GetTimeSyncManager()
	timeSyncManager.AutoSync(client)

	return &TakeProfitManager{
		client:            client,
		monitoredOrders:   make(map[int64]*TakeProfitOrder),
		isRunning:         false,
		stopChan:          make(chan struct{}),
		resistanceLevels:  make(map[string]float64),
		breakoutTriggered: make(map[string]bool),
		breakoutPrices:    make(map[string]float64),
		basePositionRate:  0.20, // 保留20%底仓
		firstSellRate:     0.30, // 首次卖出30%
		secondSellTrigger: 0.10, // 上涨10%触发二次卖出
	}
}

// Start 启动止盈监控
func (tpm *TakeProfitManager) Start() {
	tpm.mu.Lock()
	defer tpm.mu.Unlock()

	if tpm.isRunning {
		log.Println("[TAKE_PROFIT] 止盈管理器已在运行中")
		return
	}

	tpm.isRunning = true
	tpm.stopChan = make(chan struct{})
	log.Println("[TAKE_PROFIT] 止盈管理器启动成功")

	go tpm.monitorAllBuyOrders()
}

// Stop 停止止盈监控
func (tpm *TakeProfitManager) Stop() {
	tpm.mu.Lock()
	defer tpm.mu.Unlock()

	if !tpm.isRunning {
		log.Println("[TAKE_PROFIT] 止盈管理器未在运行")
		return
	}

	tpm.isRunning = false
	close(tpm.stopChan)
	log.Println("[TAKE_PROFIT] 止盈管理器已停止")
}

// monitorAllBuyOrders 监控所有买单的止盈条件
func (tpm *TakeProfitManager) monitorAllBuyOrders() {
	ticker := time.NewTicker(5 * time.Second) // 每5秒检查一次
	defer ticker.Stop()

	for {
		select {
		case <-tpm.stopChan:
			return
		case <-ticker.C:
			tpm.checkAllBuyOrdersForProfit()
			tpm.checkResistanceLevelBreakout()
		}
	}
}

// checkAllBuyOrdersForProfit 检查所有买单的止盈条件
func (tpm *TakeProfitManager) checkAllBuyOrdersForProfit() {
	// 获取所有未完成的买单
	allOrders, err := tpm.getAllOpenOrders()
	if err != nil {
		log.Printf("[TAKE_PROFIT] 获取订单列表失败: %v", err)
		return
	}

	// 过滤买单
	buyOrders := tpm.filterBuyOrders(allOrders)
	if len(buyOrders) == 0 {
		return
	}

	// 获取当前市场价格
	symbols := make(map[string]bool)
	for _, order := range buyOrders {
		symbols[order.Symbol] = true
	}

	currentPrices, err := tpm.getCurrentMarketPrices(symbols)
	if err != nil {
		log.Printf("[TAKE_PROFIT] 获取市场价格失败: %v", err)
		return
	}

	// 检查每个买单的止盈条件
	for _, order := range buyOrders {
		currentPrice, exists := currentPrices[order.Symbol]
		if !exists {
			continue
		}

		orderPrice, _ := strconv.ParseFloat(order.Price, 64)
		orderQuantity, _ := strconv.ParseFloat(order.ExecutedQuantity, 64)

		// 检查压力位突破止盈
		tpm.checkResistanceBreakoutProfit(order, currentPrice, orderPrice, orderQuantity)
	}
}

// checkResistanceBreakoutProfit 检查压力位突破止盈
func (tpm *TakeProfitManager) checkResistanceBreakoutProfit(order *binance.Order, currentPrice, orderPrice, orderQuantity float64) {
	resistanceLevel, hasResistance := tpm.GetResistanceLevel(order.Symbol)
	if !hasResistance {
		return
	}

	// 检查是否突破压力位
	if currentPrice > resistanceLevel && !tpm.breakoutTriggered[order.Symbol] {
		// 首次突破压力位，卖出30%仓位
		tpm.breakoutTriggered[order.Symbol] = true
		tpm.breakoutPrices[order.Symbol] = currentPrice
		
		firstSellQuantity := orderQuantity * tpm.firstSellRate
		log.Printf("[TAKE_PROFIT] 压力位突破! %s: 当前价格 %.8f > 压力位 %.8f，卖出30%%仓位 %.8f", 
			order.Symbol, currentPrice, resistanceLevel, firstSellQuantity)
		
		// 执行首次止盈卖出
		tpm.executeTakeProfitSell(order.Symbol, firstSellQuantity, currentPrice, "压力位突破")
		return
	}

	// 检查二次止盈条件（突破后上涨10%）
	if tpm.breakoutTriggered[order.Symbol] {
		breakoutPrice := tpm.breakoutPrices[order.Symbol]
		secondTriggerPrice := breakoutPrice * (1 + tpm.secondSellTrigger)
		
		if currentPrice >= secondTriggerPrice {
			// 卖出剩余仓位，保留20%底仓
			remainingQuantity := orderQuantity * (1 - tpm.firstSellRate) // 剩余70%
			secondSellQuantity := remainingQuantity * (1 - tpm.basePositionRate/0.7) // 保留20%底仓
			
			log.Printf("[TAKE_PROFIT] 二次止盈触发! %s: 当前价格 %.8f >= 触发价格 %.8f，卖出剩余仓位 %.8f，保留20%%底仓", 
				order.Symbol, currentPrice, secondTriggerPrice, secondSellQuantity)
			
			// 执行二次止盈卖出
			tpm.executeTakeProfitSell(order.Symbol, secondSellQuantity, currentPrice, "二次止盈")
			
			// 重置突破状态
			tpm.breakoutTriggered[order.Symbol] = false
			delete(tpm.breakoutPrices, order.Symbol)
		}
	}
}

// executeTakeProfitSell 执行止盈卖出
func (tpm *TakeProfitManager) executeTakeProfitSell(symbol string, quantity, price float64, reason string) {
	err := tpm.placeLimitSellOrder(symbol, quantity, price)
	if err != nil {
		log.Printf("[TAKE_PROFIT] %s止盈卖出失败: %v", reason, err)
		return
	}
	
	log.Printf("[TAKE_PROFIT] %s止盈卖出成功: %s, 数量: %.8f, 价格: %.8f", reason, symbol, quantity, price)
}

// getAllOpenOrders 获取所有未完成订单
func (tpm *TakeProfitManager) getAllOpenOrders() ([]*binance.Order, error) {
	return tpm.client.NewListOpenOrdersService().Do(context.Background())
}

// filterBuyOrders 过滤买单
func (tpm *TakeProfitManager) filterBuyOrders(orders []*binance.Order) []*binance.Order {
	var buyOrders []*binance.Order
	for _, order := range orders {
		if order.Side == binance.SideTypeBuy {
			buyOrders = append(buyOrders, order)
		}
	}
	return buyOrders
}

// getCurrentMarketPrices 获取当前市场价格
func (tpm *TakeProfitManager) getCurrentMarketPrices(symbols map[string]bool) (map[string]float64, error) {
	prices := make(map[string]float64)
	
	for symbol := range symbols {
		priceResp, err := tpm.client.NewListPricesService().Symbol(symbol).Do(context.Background())
		if err != nil {
			return nil, err
		}
		
		if len(priceResp) > 0 {
			price, err := strconv.ParseFloat(priceResp[0].Price, 64)
			if err != nil {
				return nil, err
			}
			prices[symbol] = price
		}
	}
	
	return prices, nil
}

// placeLimitSellOrder 下限价卖单
func (tpm *TakeProfitManager) placeLimitSellOrder(symbol string, quantity, price float64) error {
	_, err := tpm.client.NewCreateOrderService().
		Symbol(symbol).
		Side(binance.SideTypeSell).
		Type(binance.OrderTypeLimit).
		TimeInForce(binance.TimeInForceTypeGTC).
		Quantity(fmt.Sprintf("%.8f", quantity)).
		Price(fmt.Sprintf("%.8f", price)).
		Do(context.Background())
	return err
}

// SetResistanceLevel 设置压力位价格
func (tpm *TakeProfitManager) SetResistanceLevel(symbol string, price float64) {
	tpm.mu.Lock()
	defer tpm.mu.Unlock()
	tpm.resistanceLevels[symbol] = price
	log.Printf("[TAKE_PROFIT] 设置压力位: %s = %.8f", symbol, price)
}

// RemoveResistanceLevel 移除压力位
func (tpm *TakeProfitManager) RemoveResistanceLevel(symbol string) {
	tpm.mu.Lock()
	defer tpm.mu.Unlock()
	delete(tpm.resistanceLevels, symbol)
	delete(tpm.breakoutTriggered, symbol)
	delete(tpm.breakoutPrices, symbol)
	log.Printf("[TAKE_PROFIT] 移除压力位: %s", symbol)
}

// GetResistanceLevel 获取压力位价格
func (tpm *TakeProfitManager) GetResistanceLevel(symbol string) (float64, bool) {
	tpm.mu.RLock()
	defer tpm.mu.RUnlock()
	price, exists := tpm.resistanceLevels[symbol]
	return price, exists
}

// GetAllResistanceLevels 获取所有压力位
func (tpm *TakeProfitManager) GetAllResistanceLevels() map[string]float64 {
	tpm.mu.RLock()
	defer tpm.mu.RUnlock()
	result := make(map[string]float64)
	for symbol, price := range tpm.resistanceLevels {
		result[symbol] = price
	}
	return result
}

// checkResistanceLevelBreakout 检查压力位突破
func (tpm *TakeProfitManager) checkResistanceLevelBreakout() {
	tpm.mu.RLock()
	if len(tpm.resistanceLevels) == 0 {
		tpm.mu.RUnlock()
		return
	}
	
	// 复制压力位映射以避免长时间持有锁
	resistanceLevelsCopy := make(map[string]float64)
	for symbol, price := range tpm.resistanceLevels {
		resistanceLevelsCopy[symbol] = price
	}
	tpm.mu.RUnlock()
	
	// 获取当前市场价格
	symbols := make(map[string]bool)
	for symbol := range resistanceLevelsCopy {
		symbols[symbol] = true
	}
	
	currentPrices, err := tpm.getCurrentMarketPrices(symbols)
	if err != nil {
		log.Printf("[TAKE_PROFIT] 获取市场价格失败: %v", err)
		return
	}
	
	// 检查每个交易对的压力位
	for symbol, resistancePrice := range resistanceLevelsCopy {
		currentPrice, exists := currentPrices[symbol]
		if !exists {
			continue
		}
		
		// 如果当前价格突破压力位且未触发过
		if currentPrice > resistancePrice && !tpm.breakoutTriggered[symbol] {
			breakoutRate := (currentPrice - resistancePrice) / resistancePrice
			log.Printf("[TAKE_PROFIT] 压力位突破! %s: 当前价格 %.8f > 压力位 %.8f，突破幅度 %.2f%%", 
				symbol, currentPrice, resistancePrice, breakoutRate*100)
			
			// 标记突破状态
			tpm.mu.Lock()
			tpm.breakoutTriggered[symbol] = true
			tpm.breakoutPrices[symbol] = currentPrice
			tpm.mu.Unlock()
		}
	}
}

// GetMonitoringStatus 获取监控状态
func (tpm *TakeProfitManager) GetMonitoringStatus() map[string]interface{} {
	tpm.mu.RLock()
	defer tpm.mu.RUnlock()

	return map[string]interface{}{
		"is_running":         tpm.isRunning,
		"resistance_levels":  tpm.resistanceLevels,
		"breakout_triggered": tpm.breakoutTriggered,
		"breakout_prices":    tpm.breakoutPrices,
		"base_position_rate": tpm.basePositionRate,
		"first_sell_rate":    tpm.firstSellRate,
		"second_sell_trigger": tpm.secondSellTrigger,
		"last_check":         time.Now().Format("2006-01-02 15:04:05"),
	}
}

// SetStrategyParams 设置策略参数
func (tpm *TakeProfitManager) SetStrategyParams(basePositionRate, firstSellRate, secondSellTrigger float64) {
	tpm.mu.Lock()
	defer tpm.mu.Unlock()
	
	tpm.basePositionRate = basePositionRate
	tpm.firstSellRate = firstSellRate
	tpm.secondSellTrigger = secondSellTrigger
	
	log.Printf("[TAKE_PROFIT] 策略参数已更新: 底仓保留%.1f%%, 首次卖出%.1f%%, 二次触发%.1f%%", 
		basePositionRate*100, firstSellRate*100, secondSellTrigger*100)
}

// 全局止盈管理器实例
var GlobalTakeProfitManager *TakeProfitManager

// InitTakeProfitManager 初始化全局止盈管理器
func InitTakeProfitManager() {
	GlobalTakeProfitManager = NewTakeProfitManager()
	log.Println("[TAKE_PROFIT] 全局止盈管理器初始化完成")
}

// 便捷函数

// StartTakeProfitMonitoring 启动止盈监控（便捷函数）
func StartTakeProfitMonitoring() error {
	if GlobalTakeProfitManager == nil {
		return fmt.Errorf("止盈管理器未初始化")
	}
	GlobalTakeProfitManager.Start()
	return nil
}

// StopTakeProfitMonitoring 停止止盈监控（便捷函数）
func StopTakeProfitMonitoring() error {
	if GlobalTakeProfitManager == nil {
		return fmt.Errorf("止盈管理器未初始化")
	}
	GlobalTakeProfitManager.Stop()
	return nil
}

// SetResistanceLevelForSymbol 设置指定交易对的压力位（便捷函数）
func SetResistanceLevelForSymbol(symbol string, price float64) error {
	if GlobalTakeProfitManager == nil {
		return fmt.Errorf("止盈管理器未初始化")
	}
	GlobalTakeProfitManager.SetResistanceLevel(symbol, price)
	return nil
}

// RemoveResistanceLevelForSymbol 移除指定交易对的压力位（便捷函数）
func RemoveResistanceLevelForSymbol(symbol string) error {
	if GlobalTakeProfitManager == nil {
		return fmt.Errorf("止盈管理器未初始化")
	}
	GlobalTakeProfitManager.RemoveResistanceLevel(symbol)
	return nil
}

// GetTakeProfitStatus 获取止盈状态（便捷函数）
func GetTakeProfitStatus() map[string]interface{} {
	if GlobalTakeProfitManager == nil {
		return map[string]interface{}{
			"error": "止盈管理器未初始化",
		}
	}
	return GlobalTakeProfitManager.GetMonitoringStatus()
}

// SetTakeProfitStrategyParams 设置止盈策略参数（便捷函数）
func SetTakeProfitStrategyParams(basePositionRate, firstSellRate, secondSellTrigger float64) error {
	if GlobalTakeProfitManager == nil {
		return fmt.Errorf("止盈管理器未初始化")
	}
	GlobalTakeProfitManager.SetStrategyParams(basePositionRate, firstSellRate, secondSellTrigger)
	return nil
}